/**
 * 数据收集器
 * 
 * 用途：收集和缓存NeuroSky设备的脑波数据，每秒打包发送一次
 * 方法：使用Timer定时器每秒触发一次数据发送，内存中缓存原始数据
 * 原理：将一秒内接收到的所有原始脑波数据收集到列表中，定时打包成TabletBrainWaveData格式发送
 */
package com.example.brain_wave.bluetooth.collector

import com.example.brain_wave.bluetooth.model.NeuroSkyRawData
import com.example.brain_wave.bluetooth.model.TabletBrainWaveData
import java.util.*
import java.util.concurrent.ConcurrentLinkedQueue
import kotlin.collections.ArrayList

class DataCollector {
    
    // 数据缓存队列，使用线程安全的队列
    private val rawDataBuffer = ConcurrentLinkedQueue<NeuroSkyRawData>()
    
    // 定时器，用于定时发送数据
    private var timer: Timer? = null
    
    // 数据准备就绪回调
    private var onDataReady: ((TabletBrainWaveData) -> Unit)? = null
    
    // 房间ID
    private var roomId: String = ""
    
    // 获取session_id的回调函数
    private var sessionIdProvider: (() -> String?)? = null
    
    // 信号质量检测相关字段
    private var poorSignalStartTime: Long = 0  // 信号质量变差的开始时间
    private var isPoorSignalDetected: Boolean = false  // 是否检测到信号质量差
    private var isDataSendingPaused: Boolean = false  // 是否暂停数据发送
    
    companion object {
        private const val POOR_SIGNAL_THRESHOLD = 200  // 信号质量差的阈值
        private const val POOR_SIGNAL_DURATION_MS = 3000L  // 信号质量差持续时间阈值（3秒）
    }
    
    /**
     * 设置房间ID
     */
    fun setRoomId(roomId: String) {
        this.roomId = roomId
    }
    
    /**
     * 设置session_id提供者
     */
    fun setSessionIdProvider(provider: () -> String?) {
        this.sessionIdProvider = provider
    }
    
    /**
     * 设置数据准备就绪回调
     */
    fun setOnDataReady(callback: (TabletBrainWaveData) -> Unit) {
        onDataReady = callback
    }
    
    /**
     * 添加原始数据到缓存
     * 数据按照接收时间顺序存储，保证时序性
     * 同时检测信号质量，当信号质量为200持续3秒时停止发送数据
     */
    fun addRawData(data: NeuroSkyRawData) {
        // 确保数据有时间戳
        if (data.timestamp == 0L) {
            data.timestamp = System.currentTimeMillis()
        }
        
        // 检测信号质量
        checkSignalQuality(data.poorSignal)
        
        rawDataBuffer.offer(data)
    }
    
    /**
     * 检测信号质量
     * 当信号质量为200持续3秒时，暂停数据发送
     * 当信号质量恢复时，重新开始数据发送
     */
    private fun checkSignalQuality(poorSignal: Int?) {
        val currentTime = System.currentTimeMillis()
        
        if (poorSignal == POOR_SIGNAL_THRESHOLD) {
            // 信号质量差
            if (!isPoorSignalDetected) {
                // 第一次检测到信号质量差，记录开始时间
                isPoorSignalDetected = true
                poorSignalStartTime = currentTime
            } else {
                // 检查是否持续了3秒
                if (currentTime - poorSignalStartTime >= POOR_SIGNAL_DURATION_MS) {
                    if (!isDataSendingPaused) {
                        isDataSendingPaused = true
                        println("信号质量差持续3秒，暂停数据发送")
                    }
                }
            }
        } else {
            // 信号质量恢复
            if (isPoorSignalDetected || isDataSendingPaused) {
                isPoorSignalDetected = false
                isDataSendingPaused = false
                poorSignalStartTime = 0
                println("信号质量恢复，重新开始数据发送")
            }
        }
    }
    
    /**
     * 开始数据收集
     */
    fun startCollection() {
        timer = Timer("DataCollectorTimer", true)
        timer?.scheduleAtFixedRate(object : TimerTask() {
            override fun run() {
                processAndSendData()
            }
        }, 1000, 1000) // 延迟1秒开始，每1秒执行一次
    }
    
    /**
     * 停止数据收集
     */
    fun stopCollection() {
        timer?.cancel()
        timer = null
        rawDataBuffer.clear()
    }
    
    /**
     * 处理并发送数据
     * 只有在信号质量完好时才发送数据
     */
    private fun processAndSendData() {
        // 检查是否暂停数据发送
        if (isDataSendingPaused) {
            // 清空缓存但不发送数据
            rawDataBuffer.clear()
            return
        }
        
        if (rawDataBuffer.isEmpty()) {
            return
        }
        
        // 提取一秒内的所有数据
        val dataList = ArrayList<NeuroSkyRawData>()
        while (rawDataBuffer.isNotEmpty()) {
            rawDataBuffer.poll()?.let { dataList.add(it) }
        }
        
        if (dataList.isEmpty()) {
            return
        }
        
        // 按时间戳排序，确保时序性
        dataList.sortBy { it.timestamp }
        
        // 使用最新的数据作为基准
        val latestData = dataList.last()
        
        // 提取所有原始脑波值，只保留整数值
        val rawValues = dataList.mapNotNull { data ->
            data.rawValue
        }
        
        // 确保attention和meditation值在0-100范围内
        val normalizedAttention = latestData.attention?.let { 
            if (it > 100) 100 else if (it < 0) 0 else it 
        } ?: 0
        
        val normalizedMeditation = latestData.meditation?.let { 
            if (it > 100) 100 else if (it < 0) 0 else it 
        } ?: 0
        
        // 创建TabletBrainWaveData，使用会话ID而不是时间戳作为ID
        // 获取真实的session_id，如果没有则使用临时ID
        val sessionId = sessionIdProvider?.invoke() ?: "temp_session_${System.currentTimeMillis()}"
        
        val tabletData = TabletBrainWaveData(
            session_id = sessionId,
            room_id = roomId,
            timestamp = System.currentTimeMillis(),
            raw_value = rawValues,
            delta = latestData.delta ?: 0,
            theta = latestData.theta ?: 0,
            low_alpha = latestData.lowAlpha ?: 0,
            high_alpha = latestData.highAlpha ?: 0,
            low_beta = latestData.lowBeta ?: 0,
            high_beta = latestData.highBeta ?: 0,
            low_gamma = latestData.lowGamma ?: 0,
            mid_gamma = latestData.midGamma ?: 0,
            attention = normalizedAttention,
            meditation = normalizedMeditation,
            poor_signal = latestData.poorSignal ?: 0,
            blink_strength = latestData.blinkStrength ?: 0
        )
        
        // 发送数据
        onDataReady?.invoke(tabletData)
    }
    
    /**
     * 获取当前缓存的数据数量
     */
    fun getBufferSize(): Int = rawDataBuffer.size
    
    /**
     * 清空缓存
     */
    fun clearBuffer() {
        rawDataBuffer.clear()
    }
}